import java.util.Map;

/**
 * The class Operator for ex. 10. An operator can be one of 4 basic mathematical operators (+,-,*,/),
 *  and holds the two expressions that it operates on. 
 * @author Daniel Shalev
 *
 */
public class Operator implements Expression {
	private String operator;
	private Expression left ,right;
	/**
	 * Constructor that builds an Operator object. Gets the operator symbol
	 *  (+,-,*,/) and the two expressions that it operates on. 
	 * @param operator String representation of the operation.
	 * @param left The left expression.
	 * @param right The right expression.
	 */
	public Operator(String operator, Expression left, Expression right){
		this.operator=operator;
		this.left=left;
		this.right=right;
	}
	
	/**
	 * Evaluates an expression. The value of an Operator is the result of its operation on its operands.
	 *  The Map of variables is passed to the operands to evaluate the value of variables.
	 *  @param env a Map used to evaluate unknown expressions.  
	 *  @return     the value of the expression
	 */
	public double eval(Map<String, Double> env) {
		double result=0;
		if(operator.equals("-")){
			result=left.eval(env)-right.eval(env);
		}
		if(operator.equals("+")){
			result=left.eval(env)+right.eval(env);
		}
		if(operator.equals("*")){
			result=left.eval(env)*right.eval(env);
		}
		if(operator.equals("/")){
			result=left.eval(env)/right.eval(env);
		}
		return result;
	}

	
	/**
	 * String representation of the expression. This representation can be
	 *  INFIX,PREFIX or POSTFIX, depending with the requested operator order.
	 *  @param  order the operator order used to build the String.
	 *   If order==OpOrder.INFIX, brackets are added for every operation.
	 *   If order==OpOrder.POSTFIX or order==OpOrder.PREFIX, space is added between the operands.
	 *   @return     representation of the expression as String. 
	 */
	public String toString(OpOrder order) {
		String opString=null;
		String leftString = left.toString(order);
		String rightString = right.toString(order);
		if(order.compareTo(OpOrder.INFIX)==0){
			opString="(" + leftString + operator + rightString + ")";
		}
		else if(order.compareTo(OpOrder.POSTFIX)==0){
			opString=(leftString+" "+rightString+" "+operator);
		}
		else if(order.compareTo(OpOrder.PREFIX)==0){
			opString=(operator+" "+leftString+" "+rightString);
		}
		
		
		return opString;
	}

}
